package com.flea.repository.jdbc;

import lombok.Getter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jdbc.core.JdbcAggregateOperations;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class BaseRepository<T> {

    /**
     * 高度封装的JDBC操作，可直接保存实体
     */
    @Getter
    @Resource
    private JdbcAggregateOperations operations;
    /**
     * 普通命名的JDBC查询和操作，可使用 {@link org.springframework.jdbc.core.BeanPropertyRowMapper}
     * 完成高级自动装配，可自动完成驼峰和下划线的自动映射
     */
    @Getter
    @Resource
    private NamedParameterJdbcTemplate template;

    @Getter
    @Resource
    private JdbcTemplate jdbcTemplate;

    public Page<List<Map<String, Object>>> findPage(String sql, List<Object> params, Pageable pageable) {
        return findPage(sql, params, pageable, null);
    }

    public <T> Page<T> findPage(String sql, List<Object> params, Pageable pageable, Class<T> clazz) {

        //data sql
        String dataSql = sql + " limit ?,?";
        String countSql = "select count(*) " + sql.substring(sql.indexOf("from"));

        //params
        List<Object> dataPrams = new ArrayList<>(params);
        dataPrams.add(pageable.getOffset());
        dataPrams.add(pageable.getPageSize());

        List rows;
        if (clazz == null) {
            rows = jdbcTemplate.queryForList(dataSql, dataPrams.toArray());
        } else {
            rows = jdbcTemplate.query(dataSql, new BeanPropertyRowMapper<T>(clazz), dataPrams.toArray());
        }
        int total = jdbcTemplate.queryForObject(countSql, Integer.class, params.toArray());

        return PageableExecutionUtils.getPage(rows, pageable, () -> total);
    }
}